﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using StudyKitLib;  // StudyKitLib.dll 참조

namespace StudyKitNet
{
    public partial class Form1 : Form
    {
        #region PlaySound
        [DllImport("winmm.dll", EntryPoint = "PlaySound", CharSet = CharSet.Auto)]
        private static extern int PlaySound(String pszSound, int hmod, int falgs);

        public enum SND
        {
            SND_SYNC = 0x0000,/* play synchronously (default) */
            SND_ASYNC = 0x0001, /* play asynchronously */
            SND_NODEFAULT = 0x0002, /* silence (!default) if sound not found */
            SND_MEMORY = 0x0004, /* pszSound points to a memory file */
            SND_LOOP = 0x0008, /* loop the sound until next sndPlaySound */
            SND_NOSTOP = 0x0010, /* don't stop any currently playing sound */
            SND_NOWAIT = 0x00002000, /* don't wait if the driver is busy */
            SND_ALIAS = 0x00010000,/* name is a registry alias */
            SND_ALIAS_ID = 0x00110000, /* alias is a pre d ID */
            SND_FILENAME = 0x00020000, /* name is file name */
            SND_RESOURCE = 0x00040004, /* name is resource name or atom */
            SND_PURGE = 0x0040,  /* purge non-static events for task */
            SND_APPLICATION = 0x0080  /* look for application specific association */
        }

        public static void PlaySound(String pszSound)
        {
            if (File.Exists(pszSound))            
                PlaySound(pszSound, 0, (int)(SND.SND_ASYNC | SND.SND_FILENAME | SND.SND_NOWAIT));           
        }

        public static void PlaySuccess()
        {
            PlaySound("success.wav");
        }

        public static void PlayFail()
        {
            PlaySound("fail.wav");
        }
        #endregion
        
        public static RF1356.REPLY reply; // 리턴 상태를 반환하는 변수
        public static long PortNO;        // 시리얼 포트 번호   

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int i;            
            
            for (i = 1; i < 11; i++)    // COM1~10            
                cmbPort.Items.Add("COM" + i.ToString());

            for (i = 1; i < 11; i++)    // Timer Interval : 100~1000            
                cmbInterval.Items.Add((i * 100).ToString());

            for (i = 0; i < 28; i++)    // Start : 0 ~ 27 / Length : 1 ~ 28
            {
                cmbStart.Items.Add(i.ToString());
                cmbLength.Items.Add((i + 1).ToString());
            }    
            
            cmbPort.SelectedIndex     = 0;
            cmbInterval.SelectedIndex = 4;
            cmbStart.SelectedIndex    = 0;
            cmbLength.SelectedIndex   = 0;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (RF1356.RFReaderIsOpen(PortNO)) // COM 포트가 열려있으면 닫고 종료
                    RF1356.RFReaderClose(PortNO);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnAutoOpen_Click(object sender, EventArgs e)
        {
            try
            {
                for (int port = 1; port < 11; port++)
                {
                    RF1356.RFReaderOpen(port);

                    reply = RF1356.BaudDetec(port);

                    if (reply == RF1356.REPLY.RF_OK)
                    {
                        cmbPort.Enabled         = false;
                        btnAutoOpen.Enabled     = false;
                        btnPortOpen.Enabled     = false;
                        btnPortClose.Enabled    = true;
                        btnReadSerialNO.Enabled = true;
                        chkAuto.Enabled         = true;
                        cmbPort.SelectedIndex   = port - 1;
                        PortNO                  = port;
                        break;
                    }
                }

                if (reply != RF1356.REPLY.RF_OK)
                    MessageBox.Show("COM Port Open Fail", "Error",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation,
                                MessageBoxDefaultButton.Button1);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnPortOpen_Click(object sender, EventArgs e)
        {
            try
            {
                int port = cmbPort.SelectedIndex + 1;

                if (!RF1356.RFReaderOpen(port))
                {
                    MessageBox.Show("COM Port Open Fail", "Error",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation,
                                MessageBoxDefaultButton.Button1);
                }
                else
                {
                    cmbPort.Enabled         = false;
                    btnAutoOpen.Enabled     = false;
                    btnPortOpen.Enabled     = false;
                    btnPortClose.Enabled    = true;
                    btnReadSerialNO.Enabled = true;
                    chkAuto.Enabled         = true;
                    PortNO = port;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }     
        }

        private void btnPortClose_Click(object sender, EventArgs e)
        {
            try
            {
                if (RF1356.RFReaderClose(PortNO))
                {
                    btnAutoOpen.Enabled     = true;
                    btnPortOpen.Enabled     = true;
                    btnPortClose.Enabled    = false;
                    btnReadSerialNO.Enabled = false;
                    btnReadData.Enabled     = false;
                    btnWriteData.Enabled    = false;
                    cmbPort.Enabled         = true;
                    chkAuto.Enabled         = false;
                    
                    try
                    {
                        if (RF1356.RFReaderIsOpen(PortNO))
                            RF1356.RFReaderClose(PortNO);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void grdView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                txtSelTag.Text = grdView1[0, grdView1.CurrentRow.Index].Value.ToString();
            }
            catch (Exception ex) { }
        }

        private void chkAuto_CheckedChanged(object sender, EventArgs e)
        {
            if (chkAuto.Checked)
            {
                timer1.Enabled = true;

                btnPortClose.Enabled    = false;
                btnReadSerialNO.Enabled = false;
                btnReadData.Enabled     = false;
                btnWriteData.Enabled    = false;
            }
            else
            {
                timer1.Enabled = false;

                btnPortClose.Enabled    = true;
                btnReadSerialNO.Enabled = true;
                btnReadData.Enabled     = true;
                btnWriteData.Enabled    = true;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Interval = int.Parse(cmbInterval.Text);

            btnReadSerialNO_Click(sender, e);
        }

        private void btnReadSerialNO_Click(object sender, EventArgs e)
        {
            int tagCnt = 0;
            string SerialNumbers = String.Empty;

            grdView1.Rows.Clear();
            lblCount.Text = "00";

            reply = RF1356.RFReadSerialNO(PortNO, ref SerialNumbers);

            switch (reply)
            {
                case RF1356.REPLY.RF_OK:
                    lblCount.Text = SerialNumbers.Substring(0, 2);
                    tagCnt = int.Parse(SerialNumbers.Substring(0, 2));

                    for (int i = 0; i < tagCnt; i++)
                    {
                        string str = SerialNumbers.Substring(2 + (16 * i), 16);
                        string UID = String.Empty;
                        string Maker = String.Empty;

                        for (int j = 0; j < 8; j++)
                        {
                            UID = str.Substring(2 * j, 2) + UID;
                        }

                        Maker = UID.Substring(2, 2);

                        switch (Maker)
                        {
                            case "04":
                                Maker = "PHILIPS";
                                break;

                            case "05":
                                Maker = "INFINEON";
                                break;

                            case "07":
                                Maker = "TI";
                                break;

                            default:
                                break;
                        }

                        grdView1.Rows.Add(new string[] { UID, Maker }); //lstUID1.Items.Add(UID); 

                        if ((i % 2) == 0)
                        {
                            grdView1[0, i].Style.BackColor = Color.Aqua;
                            grdView1[1, i].Style.BackColor = Color.Aqua;
                        }
                        else
                        {
                            grdView1[0, i].Style.BackColor = Color.LightSteelBlue;
                            grdView1[1, i].Style.BackColor = Color.LightSteelBlue;
                        }
                    }

                    if (chkSnd.Checked)
                        PlaySuccess();

                    if (!chkAuto.Checked)
                    {
                        btnReadData.Enabled = true;
                        btnWriteData.Enabled = true;
                    }
                    break;

                case RF1356.REPLY.NO_TRANSPONDER:
                    if (chkSnd.Checked)
                        PlayFail();
                    grdView1.Rows.Add(new string[] { "No Tag", "" });
                    break;

                case RF1356.REPLY.RF_ERR:
                    if (chkSnd.Checked)
                        PlayFail();
                    grdView1.Rows.Add(new string[] { "Error", "" });
                    break;

                default:
                    break;
            }
        }

        private void btnReadData_Click(object sender, EventArgs e)
        {
            txtAscR.Text.Remove(0, txtAscR.Text.Length);
            txtHexR.Text.Remove(0, txtHexR.Text.Length);

            if (txtSelTag.Text == "" || txtSelTag.Text.Trim().Length != 16)
            {
                MessageBox.Show("Select Tag UID", "Error",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation,
                                MessageBoxDefaultButton.Button1); 
                return;
            }

            string UID        = txtSelTag.Text;
            string DataBlocks = String.Empty;
            string Data       = String.Empty;
            int start         = int.Parse(cmbStart.SelectedItem.ToString());
            int length        = int.Parse(cmbLength.SelectedItem.ToString());

            reply = RF1356.RFReadDataBlock(PortNO, UID, ref DataBlocks, start, length);

            switch (reply)
            {
                case RF1356.REPLY.RF_OK:
                    txtHexR.Text = DataBlocks;
                    txtAscR.Text = RF1356.hex2str(DataBlocks);
                    PlaySuccess();
                    break;

                case RF1356.REPLY.NO_TRANSPONDER:
                    grdView1.Rows.Clear();
                    grdView1.Rows.Add(new string[] { "No Tag", "" });
                    PlayFail();
                    break;

                case RF1356.REPLY.RF_ERR:
                    grdView1.Rows.Clear();
                    grdView1.Rows.Add(new string[] { "Error", "" });
                    PlayFail();
                    break;

                case RF1356.REPLY.INVALID_PARAMETER:
                    grdView1.Rows.Clear();
                    grdView1.Rows.Add(new string[] { "Invalid Parameter", "" });
                    PlayFail();
                    break;

                default:
                    break;
            }
        }  
   
        private void btnWriteData_Click(object sender, EventArgs e)
        {
            if (txtSelTag.Text == "" || txtSelTag.Text.Trim().Length != 16)
            {
                MessageBox.Show("Select Tag UID", "Error",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation,
                                MessageBoxDefaultButton.Button1); 
                return;
            }

            string UID        = txtSelTag.Text;
            string DataBlocks = String.Empty;
            string Data       = String.Empty;
            int start         = int.Parse(cmbStart.SelectedItem.ToString());
            int length        = int.Parse(cmbLength.SelectedItem.ToString());

            DataBlocks = RF1356.str2hex(txtAscW.Text);            

            reply = RF1356.RFWriteDataBlock(PortNO, UID, ref DataBlocks, start, length);

            switch (reply)
            {
                case RF1356.REPLY.RF_OK:
                    MessageBox.Show("Write Success", "OK",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Asterisk,
                                MessageBoxDefaultButton.Button1);
                    break;

                case RF1356.REPLY.NO_TRANSPONDER:
                    grdView1.Rows.Clear();
                    grdView1.Rows.Add(new string[] { "No Tag", "" });
                    PlayFail();
                    break;

                case RF1356.REPLY.RF_ERR:
                    grdView1.Rows.Clear();
                    grdView1.Rows.Add(new string[] { "Error", "" });
                    PlayFail();
                    break;

                case RF1356.REPLY.INVALID_PARAMETER:
                    grdView1.Rows.Clear();
                    grdView1.Rows.Add(new string[] { "Invalid Parameter", "" });
                    PlayFail();
                    break;

                default:
                    break;
            }
        }        
    }
}